iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 13
0

Pipe 是用在 Interpolation 或是 Property Binding 時,幫我們做資料格式的轉換,比方說我們要將字串轉成全大寫,可以用內建的 method toUpperCase()

// homepage.component.ts

constructor() {
    this.name = 'Henry';
    this.name = this.name.toUpperCase();
}
// homepage.component.html

<p> My name is {{ name }}.</p>

name 就會以全大寫的方式顯示。

使用官方提供的 Pipe

但是 Angular 有更方便的 Pipe 可以使用,語法也很簡單,以上面的轉換大寫為例,使用 Pipe 的話,我們只需要這樣寫:

// homepage.component.ts
name = 'Henry';
// homepage.component.html

<p> My name is {{ name | uppercase }}.</p>

就會像上面一樣把字轉換成全大寫。

這個 Pipe 呢,其實在 Linux 系統下也很常用到,我想最常用的就是 grep 了。
下面的ls 就是列出當前目錄有哪些檔案,然後透過 Linux的 Pipe,將 ls 的結果丟給 grep 做處理,grep會用 regular expression (正規表達式) 來過濾掉不相符的字串。
這邊我們設定的 regular expression 就是 .json,所以 ls | grep .json,就會把檔名中沒有 .json 的檔案過濾掉,只列出包含 .json 的檔案。這跟 Angular 的 Pipe 原理是一樣的。

當然也可以這樣使用,我有一個文字檔,放了一些單字,我一樣可以使用 grep,來篩選單字,下面的例子就是用 cat 顯示檔案,並且分別輸出只包含 ap 以及 ab 的單字。

以上是一點小補充。

其他還有像 DatePipe、PercentPipe、CurrencyPipe 等內建的 Pipe:

DatePipe

這邊初始日期的地方雖然填 8,但實際上是設定九月,Mouth 的設定範圍是 0 ~ 11 ,0 代表一月,11代表12月,我也覺得很奇怪

// homepage.component.ts

holiday = new Date(2019, 8, 28);
// homepage.component.html

<p> Today is {{ holiday | date }} </p>

預設會輸出這樣的格式 :

Pipe 也可以加上參數,參數用分隔。比方說我們想調整顯示格式跟時區,第一個參數我放時間格式 "MM/dd hh:mm:ss",第二個參數我放時區"+0900" ,結果如下:

// homepage.component.html

<p> Today is {{ holiday | date:"MM/dd hh:mm:ss":"+0900" }} </p>

或是可以使用 Angular 定義好的一些格式 long、medium、short等等。在Angular官方手冊都可以查到。下面是使用預定義格式 long 的結果:

// homepage.component.html

<p> Today is {{ holiday | date:"long":"+0500" }} </p>

並且 Pipe可以串聯使用,下面一併示範在 Property Binding 使用
CurrencyPipe,以及串接 Pipe,其實就只是單純用 | 繼續串聯下一個 Pipe指令:

// homepage.component.ts

price = 87.735;
// homepage.component.html

<input type="submit" [value]="price | currency:'CAD'| lowercase">

結果如下:

自訂自己的 Pipe

下指令建立一個 Pipe:

ng generate pipe <pipe name>

Pipe 同樣有 alias,所以也可以這樣下:

ng g p <pipe name>

就算建立時忘記打 pipe 的名字,Anglar 也會很貼心的問我們要怎麼命名:

我這邊用凱薩加密法示範,所以我命名為 Caesar
Angular 會幫我們建立兩個檔案,並修改 app.module.ts,將CaesarPipe 放進 @NgModuledeclarations,這部分與建立 Component 類似。

接下來切換到 caesar.pipe.ts,在 transform 填入要傳入的參數,以及回傳值的型別,還有 pipe 要如何轉換這筆資料。
第一個參數必須放你傳入要處理的資料,也就是 {{plainText | caesar:10}} 的 plainText。

plaintext 是我輸入的明文,offset 是傳入的偏移量,這邊是將每個字轉成 ascii code,加上偏移量再與 26 取模數,最後再轉回字串。

程式碼如下: (code真醜

// caesar.pipe.ts

  transform(plaintext: string, offset: number): string {

    let cipherText = '';

    for (const char of plaintext) {
      const charASCII = char.charCodeAt(0);
      if (char >= 'a' && char <= 'z') {

         let cipherchar = (charASCII - 'a'.charCodeAt(0) + offset);
         while (cipherchar < 0) { cipherchar += 26; }
         cipherText += String.fromCharCode(cipherchar % 26 + 'a'.charCodeAt(0));

      } else if (char >= 'A' && char <= 'Z') {

        let cipherchar = (charASCII - 'A'.charCodeAt(0) + offset);
        while (cipherchar < 0) { cipherchar += 26; }
        cipherText += String.fromCharCode(cipherchar  % 26 + 'A'.charCodeAt(0));

      }
    }
    return cipherText;
  }

如此一來就能使用一個簡單的凱薩加密法 Pipe了:

// homepage.component.html

<p> Plaintext :{{plainText}}, ciphertext :{{plainText | caesar:-10}}</p>
<p> Plaintext :{{plainText}}, ciphertext :{{plainText | caesar:50}}</p>
<p> Plaintext :{{plainText}}, ciphertext :{{plainText | caesar:100}}</p>


上一篇
# DAY 12 Directive - Attribute directives
下一篇
# DAY 14 自訂 Directive
系列文
從零開始的Angular前端開發30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言